package com.huaqin.salestracker;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;

import org.xmlpull.v1.XmlPullParserException;

import com.huaqin.common.Featrue;
import com.huaqin.common.NVRAM;
import com.huaqin.common.Util;
import com.huaqin.customer.ConditionManger;
import com.huaqin.customer.CustomerInformation;
import com.huaqin.customer.MessageManager;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.IBinder;
//import android.os.SystemProperties;
import android.util.Log;

public class SalesTrackerService extends Service {
	
	private static final String TAG = "SalesTrackerService";
	private static final String UNKOWNADDRESS = "Unkwon Address";
	public static Context mContext;
	
	public static boolean mSystemDebug = false; //System Debug flat by Config
	public static final boolean MTK_GEMINI_SUPPORT = true; //FeatureOption.MTK_GEMINI_SUPPORT;
	
	public static final String HUAQIN_APP = "HUAQIN_APP";
	public static final String CUSTOMER_APP = "CUSTOMER_APP";
	public static final String NONE_APP = "NONE";

	public static final String XMLFILEPATH = "mnt/sdcard/customer.xml";

	public static final String SECRET_CODE = "android.provider.Telephony.SECRET_CODE";
	public static final String BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
	public static final String SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
	
	public static final String SEND_SMS_ACTION = "android.intent.action.SEND_DIRECT_SMS";

	public static final String STCMD_START_ACTION = "com.huaqin.salestrackerservice.start"; //Receiver onReceiver()
	public static final String STCMD_UPDATE_ACTION = "com.huaqin.salestrackerservice.update"; //Activity onCreate()
	public static final String STCMD_RUN_ACTION = "com.huaqin.salestrackerservice.run"; //Activity start service
	public static final String STCMD_STOP_ACTION = "com.huaqin.salestrackerservice.stop"; //Activity stop service
	public static final String STCMD_UPDATE_CONFIG = "com.huaqin.salestrackerservice.config"; //update config by activity

	public static final String STCMD_SEND_ACTION = "com.huaqin.salestrackerservice.sendmessage"; //All Sender must register
	public static final String STCMD_SEND_AREADY = "com.huaqin.salestrackerservice.aready";//All Condition must register
	public static final String STCMD_SEND_RESULT = "com.huaqin.salestrackerservice.sendresult";
	public static final String STCMD_SEND_FEEDBACK = "com.huaqin.salestrackerservice.feedback";

	//Save to preference
	public static final String KEY_RESIGER = "Resigter";
	public static final String KEY_ADDRESS = "Address";
	public static final String KEY_MESSAGE = "Message";
	public static final String KEY_FEEDBACK = "Feedback";
	public static final String KEY_RESULT = "Result";
	public static final String KEY_FAILURE = "Cause"; //failure status
	public static final String KEY_VISIBLE = "Visible";

	public static final String KEY_LAST_ADDRESS = "Last_Address";
	public static final String KEY_LAST_MESSAGE = "Last_Message";

	private static final String SEND_TYPE_NOMAL = "normal";
	private static final String SEND_TYPE_FEEDBACK = "feedback";
	private String mSendType = SEND_TYPE_NOMAL;
	
	public static final String SHARED_NAME = "SalesTrackerSystem";
	
	public static final long BOOT_COMPLETED_TIME = 1 * 60 * 1000;
	public static final long ONE_MINUTES = 60 * 1000;
	public static final long DEFAULT_INTERVAL = 10 * 60 * 1000; 
	public static final int DEFAULT_TIME = 3;
	public static int mSMSSendMode;

	//System status for Activity display 
	public static final int STATUS_SYSTEM_PREPARE = 0;
	public static final int STATUS_WAIT_AREAGY = 1;
	public static final int STATUS_WAIT_RESULT = 2;
	public static final int STATUS_WAIT_FEEDBACK = 3;
	public static final int STATUS_RESIGTER_SUCCESS = 4;
	public static final int STATUS_FAILED_RETRY_SEND = 5;
	public static final int STATUS_FAILED_FEEDBACK_SEND = 6;
	
	public static int mSystemStatus = STATUS_SYSTEM_PREPARE;

	//about send config
	private String mLastAddress;
	private String mLastMessage;
	
	public static ArrayList<HashMap<String, Object>> mConfigItemList = null;
	public static boolean mIsConfirm = false;
	public static boolean mIsRetry = false;
	public static boolean mIsFeedback = false;
	public static boolean mIsHintSuccess = false;
	public static int mRetrySend = 0;		//sent count
	public static int mFeedbackSend = 0;	//sent count
	public static int mRetryTime;
	public static int mFeedbackTime;
	public static long mRetryInterval;
	public static long mFeedbackInterval;
	
	public SalesTrackerConfiguration mConfiguration;
	private String mSystemInfo; // HUAQIN_APP CUSTOMER_APP NONE
	private CustomerInformation mCustomerInformation;
	private ConditionManger mConditionManger;
	private MessageManager mMessageManager;
	private boolean mIsRegister = false;
	private boolean mReceiverUnregistered = false;
	private boolean mParserResult = false;
	private boolean mStartByActivity = false; // start by activity or brocast
	
	private AlarmManager mAlarmManager;
	private SharedPreferences mSharedPreferences;
	private BroadcastReceiver mExternalReceiver = null;

	private Thread mServiceInitThread = new Thread(new Runnable() {
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			mParserResult = serviceInit();
		}
	});

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.d(TAG, ">> onBind()");
		
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i(TAG, ">> onStartCommand()");
		
		if(intent != null){
			String action = intent.getAction();
			Log.i(TAG, "Action:[" + action + "]");

			if(action == null){
				return START_STICKY;
			}

			if(!mIsRegister && mParserResult && action.equals(STCMD_START_ACTION)){
				setAllConditionsRun();
			}
			else if(action.equals(STCMD_UPDATE_ACTION)){
				//get current and show status to activity
				mStartByActivity = intent.getBooleanExtra(KEY_VISIBLE, false);
				
				Log.d(TAG, "STCMD_UPDATE_ACTION mStartByActivity = " + mStartByActivity);
				
				broadcastServiceStatus();
			}
			else if(action.equals(STCMD_UPDATE_CONFIG)){
				updatePreferencesExternal(intent, mConfigItemList);
				broadcastServiceStatus();
			}
			else if(action.equals(STCMD_RUN_ACTION)){
				setAllConditionsRun();
			}
			else if(action.equals(STCMD_STOP_ACTION)){
				stopService();
			}
		}

		Log.d(TAG, "<< onStartCommand()");
		
		return START_STICKY;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		
		Log.i(TAG, ">> onCreate()");

		mContext = getApplicationContext();	
		mSharedPreferences = getSharedPreferences(SHARED_NAME, Context.MODE_PRIVATE);
		mIsRegister = NVRAM.isRegister();

		mServiceInitThread.start();

		try {
			mServiceInitThread.join();

			if(mParserResult && mSystemInfo.equalsIgnoreCase(HUAQIN_APP)){
				updatePreferencesInternal();
				Log.d(TAG, "Xml file parser success!");
			}
			else{
				Log.e(TAG, "Service stopSelf");
				stopSelf();
				return;
			}
		}
		catch (InterruptedException e) {
			// TODO Auto-generated catch block
			Log.e(TAG, "Service InterruptedException");
		}

		if(mIsRegister){
		    Log.e(TAG, " ==> SalesTracker Resigsted!");
		    stopSelf();
		}
		else{
		    mAlarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
		    registerReceiveListener();
		}

		Log.i(TAG, "<< onCreate()");
	}

	@Override
	public void onLowMemory() {
		// TODO Auto-generated method stub
		Log.e(TAG, ">> SalesTrackerService onLowMemory()");
		
		super.onLowMemory();
		
		Log.e(TAG, "<< SalesTrackerService onLowMemory()");
	}

	private void setAllConditionsRun(){
		
		Log.i(TAG, ">> Set All Conditions Run");
		
		if(mConditionManger.updateAllTriggerStatus()){
			
			Log.i(TAG, "Condition Aready, Sending");

			final Intent sendIntent = new Intent(STCMD_SEND_ACTION);
			sendIntent.putExtra(KEY_ADDRESS, mLastAddress);
			sendIntent.putExtra(KEY_MESSAGE, mLastMessage);
			sendBroadcast(sendIntent);
			
			Log.d(TAG, "Send Broadcast");

			mSystemStatus = STATUS_WAIT_RESULT;
		}

	}
	
	private class Receiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            if(mReceiverUnregistered || intent == null){
                return;
            }
            
            String action = intent.getAction();
            Log.i(TAG,"onReceive action:[" + action + "]");

            //This action send by sub condition
            if(action.equals(STCMD_SEND_AREADY) && mConditionManger.updateAllTriggerStatus()){
                
                mConditionManger.finishAllTrigger();
                
                if(mIsConfirm){
                    confirmBeforeSend();
                }
                else{
                    final String address = getSendAddress();
                    final String message = getSendMessage();
                    
                    Log.i(TAG, "Condition Aready, Sending [" + message + "] to [" + address + "]");
                    
                    final Intent sendIntent = new Intent(STCMD_SEND_ACTION);
                    sendIntent.putExtra(KEY_ADDRESS, address);
                    sendIntent.putExtra(KEY_MESSAGE, message);
                    sendBroadcast(sendIntent);
                    
                    mLastAddress = address;
                    mSystemStatus = STATUS_WAIT_RESULT;
                    
                    broadcastServiceStatus();
                    
                    Util.setStringPref(context, KEY_LAST_ADDRESS, mLastAddress);
                }
            }
            //This action sned by sub sender
            else if(action.equals(STCMD_SEND_FEEDBACK)){
                
                Log.i(TAG, "Register by sender feedback");
                
                mSystemStatus = STATUS_RESIGTER_SUCCESS;
                broadcastServiceStatus();
                
                NVRAM.Register();
                NVRAM.addRecordLog(" ====> Sales Tracker Resiger");
                
                stopSelf();
            }
            //This action send by sub sender
            else if(action.endsWith(STCMD_SEND_RESULT)){
                boolean sendResult = intent.getBooleanExtra(KEY_RESULT, false);

                //send success
                if(sendResult){
                    
                    Log.i(TAG, "Receiver Result: Success");
                    
                    if(mIsFeedback && mFeedbackSend < mFeedbackTime && mSystemStatus == STATUS_WAIT_FEEDBACK){
                        
                        Log.i(TAG, "Feedback Message");
                        
                        mSystemStatus = STATUS_WAIT_FEEDBACK;
                        broadcastServiceStatus();
                        
                        Intent sendIntent = new Intent(STCMD_SEND_ACTION);
                        sendIntent.putExtra(KEY_ADDRESS, mLastAddress);
                        sendIntent.putExtra(KEY_MESSAGE, mConfiguration.mSendFeedback.getFeedbackMsg());
                        sendBroadcast(sendIntent);
                        
                        NVRAM.addRecordLog(" ====> Sales Tracker Feedback to Service center!");
                    }
                    else{
                        Log.i(TAG, " ==> Register <==");
                        NVRAM.addRecordLog("Register Address:" + mLastAddress);
                        
                        mSystemStatus = STATUS_RESIGTER_SUCCESS;
                        broadcastServiceStatus();
                        
                        NVRAM.Register();
                        stopSelf();
                    }
                }
                //failed
                else{
                    String failureCause = intent.getStringExtra(KEY_FAILURE);
                    Log.e(TAG, "Send Failed:" + failureCause);

                    if(failureCause != null && failureCause.equals(UNKOWNADDRESS)){
                        stopSelf();
                    }

                    if(mSendType.equals(SEND_TYPE_NOMAL)){
                        sendRetry();
                    }
                    else if(mSendType.equals(SEND_TYPE_FEEDBACK)){
                        feedbackRetry();
                    }
                }
            }
        }
	    
	}
	
	private void registerReceiveListener(){
		if(mExternalReceiver == null){
		    mExternalReceiver = new Receiver();
		}

		IntentFilter commandFilter = new IntentFilter();
        commandFilter.addAction(STCMD_SEND_AREADY);
        commandFilter.addAction(STCMD_SEND_FEEDBACK);
        commandFilter.addAction(STCMD_SEND_RESULT);
        registerReceiver(mExternalReceiver, commandFilter);
	}

	private boolean serviceInit(){
		
		Log.d(TAG, ">> serviceInit()");
		boolean parserResult = false;

		try {
			mConfiguration = new SalesTrackerConfiguration(this);
			
			//String xmlFile = SystemProperties.get("ro.sales.tracker.config", "customer.xml");
			
			InputStream is = getAssets().open("customer.xml");
			
			parserResult = mConfiguration.parse(is);
			
			is.close();

			if(parserResult){
				
				mSystemInfo = mConfiguration.getSystemInfo();
				Log.e(TAG, "System Sales Tracker is :[" + mSystemInfo + "]");

				if(mSystemInfo != null && mSystemInfo.equalsIgnoreCase(HUAQIN_APP)){
				    
					mCustomerInformation = mConfiguration.getCustomerInformation();
					mConditionManger = mConfiguration.getConditionManger();
					mMessageManager = mConfiguration.getMessageManager();
					
					if(mCustomerInformation != null && mConditionManger != null && mMessageManager != null){

						mSMSSendMode = mMessageManager.getSMSSendMode();
						mMessageManager.setContext(mContext);
						mMessageManager.Init();
						
						mSystemDebug = mConfiguration.isSystemDebugMode();
    					Featrue.setDebug(mSystemDebug);
    					
    					ArrayList<HashMap<String, Object>> itemList = mConfiguration.getListViewItem();

    					if(!mSystemDebug && !itemList.isEmpty()){
    					    
    					    if(mConfigItemList == null){
                                mConfigItemList = new ArrayList<HashMap<String, Object>>();
                            }

    					    String[] displayItem = getResources().getStringArray(R.array.perf_allow_tester_modify);
    					    int len = itemList.size();
    					    
    					    for(int i = 0; i< len ; i++){
    					        
    					        String itemName = (String)itemList.get(i).get("item");
    					        
    					        for(int j = 0; j < displayItem.length; j++){
    					            
    					            if(itemName.equals(displayItem[j])){
    					                mConfigItemList.add(itemList.get(i));
    					            }
    					            else{
    					                continue;
    					            }
    					        }
    					        
    					    }
    					    
    					    itemList.clear();
    					}
    					else{
    					    mConfigItemList = itemList;
    					}
					}
					else{
						Log.e(TAG,"Configuration Init Failed!");
					}
				}
			}
		}
		catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			Log.e(TAG, "Xml file XmlPullParserException");
		}
		catch (Exception e) {
			// TODO Auto-generated catch block
			Log.e(TAG, "Xml file Exception");
		}

		Log.d(TAG, "<< serviceinit() Result:" + parserResult);
		return parserResult;
	}

	//Broadcast service status to activity
	private void broadcastServiceStatus(){
		
		if(mStartByActivity){
		    String[] status = getResources().getStringArray(R.array.perf_system_status);
	        String systemstatus = status[mSystemStatus];
	        String conditionDescriptions = mConditionManger.getConditionDescription();
	        
	        Intent intent = new Intent();
	        intent.setAction("com.huaqin.salesactivity.update");
	        intent.putExtra("status", systemstatus);
	        intent.putExtra("description", conditionDescriptions);
	        sendBroadcast(intent);
		}
	}

	private void sendRetry(){

		mSystemStatus = STATUS_FAILED_RETRY_SEND;
		broadcastServiceStatus();

		mRetrySend++;
		NVRAM.addRecordLog("Register result Failed!");
		
		if(mIsRetry && mRetrySend < mRetryTime - 1){
			
			Log.i(TAG, "Retry:" + mRetrySend + "/" + mRetryTime + " Interval:" + mRetryInterval + "ms");
			
			String address = getSendAddress(); //Reacquire the next address
			Intent sendIntent = new Intent(STCMD_SEND_ACTION);
			sendIntent.putExtra(KEY_ADDRESS, address);
			sendIntent.putExtra(KEY_MESSAGE, mLastMessage);
			
			Log.i(TAG, "sendRetry address:" + address);
			mLastAddress = address;
			Util.setStringPref(mContext, KEY_LAST_ADDRESS, mLastAddress);
			
		    PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, sendIntent, PendingIntent.FLAG_UPDATE_CURRENT);
		    mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + mRetryInterval, pendingIntent);
		}
		else{
		    stopSelf();
		}
	}

	private void feedbackRetry(){
		
		Log.i(TAG, "FeedbackRetry");
		
		mSystemStatus = STATUS_FAILED_FEEDBACK_SEND;
		broadcastServiceStatus();
		
		mFeedbackSend++;
		NVRAM.addRecordLog("Feedback result Failed!");
		
		if(mIsFeedback && mFeedbackSend < mFeedbackTime - 1){
			
			Log.i(TAG, "Retry:" + mFeedbackSend + "/" + mFeedbackTime + " Interval:" + mFeedbackInterval + "ms");
			
			Intent sendIntent = new Intent(STCMD_SEND_ACTION);
			sendIntent.putExtra(KEY_ADDRESS, mLastAddress);
			sendIntent.putExtra(KEY_MESSAGE, mConfiguration.mSendFeedback.getFeedbackMsg());

		    PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, sendIntent, 0);
		    mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + mFeedbackInterval, pendingIntent);
		}
		else{
            stopSelf();
        }
	}

	private void updatePreferencesExternal(Intent intent, ArrayList<HashMap<String, Object>> ConfigItemList){
		if(intent == null || ConfigItemList == null){
			return;
		}
		
		int index = intent.getIntExtra("Index", -1);
		String value = intent.getStringExtra("Value");
		
		HashMap<String, Object> item = ConfigItemList.get(index);
		item.put("value", value);
		ConfigItemList.set(index, item);
		
		String itemName = item.get("item").toString();
		Log.v(TAG, "Modify Item " + itemName + " ==> " + value);
		
		if(itemName.equals("ConfirmSwitch")){
			mIsConfirm = value.equalsIgnoreCase("true") || value.equalsIgnoreCase("on") || value.equals("1") ? true :false;
		}
		else if(itemName.equals("RetrySwitch")){
			mIsRetry = value.equalsIgnoreCase("true") || value.equalsIgnoreCase("on") || value.equals("1") ? true :false;
		}
		else if(mIsRetry && itemName.equals("RetryInterval")){
			mRetryInterval = Integer.parseInt(value) * ONE_MINUTES  ;
		}
		else if(mIsRetry && itemName.equals("RetryTime")){
			mRetryTime = Integer.parseInt(value);
		}
		else if(itemName.equals("FeedbackSwitch")){
			mIsFeedback = value.equalsIgnoreCase("true") || value.equalsIgnoreCase("on") || value.equals("1") ? true :false;
		}
		else if(mIsFeedback && itemName.equals("FeedbackInterval")){
			mFeedbackInterval = Integer.parseInt(value) * ONE_MINUTES  ;
		}
		else if(mIsFeedback && itemName.equals("FeedbackTime")){
			mFeedbackTime = Integer.parseInt(value);
		}
		else if(itemName.equals("HintSuccessSwitch")){
			mIsHintSuccess = value.equalsIgnoreCase("true") || value.equalsIgnoreCase("on") || value.equals("1") ? true :false;
		}
		else if(itemName.equals("Address")){
			mLastAddress = value;
			Util.setStringPref(this, KEY_LAST_ADDRESS, mLastAddress);
		}
		else if(itemName.equals("SMSSendMode")){
		    mSMSSendMode = Integer.parseInt(value);
		}
	}

	private void updatePreferencesInternal(){
		
		Log.i(TAG, "updatemPreferences");

		Util.setStringPref(mContext, SalesTrackerSLable.APP, mSystemInfo);
		Util.setStringPref(mContext, SalesTrackerSLable.MODEL, mCustomerInformation.getModel());
		Util.setStringPref(mContext, SalesTrackerSLable.PRODUCT, mCustomerInformation.getProduct());
		Util.setStringPref(mContext, SalesTrackerSLable.PLATFORM, mCustomerInformation.getPlatform());

		mIsConfirm = mConfiguration.mConfirm.getConfirmValues();
		
		mIsRetry = mConfiguration.mSendRetry.getRestryValues();
		if(mIsRetry){
			mRetryInterval = mConfiguration.mSendRetry.getRetryInterval();
			mRetryTime = mConfiguration.mSendRetry.getRetryTime();
		}
		
		mIsFeedback = mConfiguration.mSendFeedback.getFeedbackValues();
		if(mIsFeedback){
			mFeedbackInterval = mConfiguration.mSendFeedback.getFeedbackInterval();
			mFeedbackTime = mConfiguration.mSendFeedback.getFeedbackTime();
		}
		
		mIsHintSuccess = mConfiguration.mConfirm.getHintSuccessValues();
	}
	
	private String getSendAddress(){
	    String address = null;
	    address = Util.getStringPref(this, KEY_ADDRESS, null);
	    if(address != null){
	        return address;
	    }

        try {
            address = (mMessageManager != null) ? mMessageManager.getSendAddress().getAddress() : null;
            if(address != null){
                mLastAddress = address;
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }

		return mLastAddress;
	}
	
	private String getSendMessage(){
	    String message = (mMessageManager != null) ? mMessageManager.getSendMessage() : null;
	    if(message != null){
            mLastMessage = message;
	    }  
	    return mLastMessage;
	}
	
	private void stopService(){

		if(mExternalReceiver != null){
            unregisterReceiver(mExternalReceiver);
            mExternalReceiver = null;
		}
        
		if(mConditionManger != null){
            mConditionManger.finishAllTrigger();
		}

		mReceiverUnregistered = true;
	}
	
	//Only confirmed when the first run
	private void confirmBeforeSend(){
		
		Log.i(TAG, "ConfirmBeforeSend");

//		String title = mConfiguration.mConfirm.
//		
//		new AlertDialog.Builder(this).setTitle("提示")
//	        .setMessage("确定退出?")
//	        .setIcon(android.R.drawable.ic_dialog_alert)
//	        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
//	
//	            public void onClick(DialogInterface dialog, int whichButton) {
//	
//	                System.exit(0);
//	            }
//	        })
//	        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
//	            public void onClick(DialogInterface dialog, int whichButton) {
//	                //取消按钮事件
//	                 Dissmis();
//	            }
//	        })
//	        .show();
		
	}
	
	private void hintSuccessAfterResigter(){
		//mConfiguration.mConfirm.setHintToCustomer(mContext, mConfiguration.mConfirm.HINT_TYPE_HINT_OK);
	}

	@Override
	public boolean onUnbind(Intent intent) {
		// TODO Auto-generated method stub
		return super.onUnbind(intent);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i(TAG, ">> onDestroy()");

		stopService();
		
		Log.i(TAG, "<< onDestroy()");
		super.onDestroy();
	}
	
}
